﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cofe.Core.Validater;
using Cofe.Core;
using Cofe.Core.EntryType;
using Cofe.Core.Property;
using Cofe.Core.Entry;
using Cofe.Core.Interfaces;
using Cofe.Core.Security;
using Cofe.Web;
#if NETFX_CORE
using Windows.UI.Xaml.Media.Imaging;
#else                                           
using System.Windows.Media.Imaging;
#endif

namespace Cofe.Core
{
    #region CacheProperties {00-09}

    /// <summary>
    /// {00-09} A list of properties implemented by IPropertyCache
    /// </summary>
    [PropertyId(00, 09)]
    public enum CacheProperties : int
    {
        /// <summary>
        /// Get the id.
        /// </summary>
        [PropertyType(PropertyTypeAttribute.GuidDefaultEnum.Empty)]
        [WebProperty(PropertyXmlType.Attribute)]
        [Alias("Id")]
        [Cachable(PropertyCacheOptions.Cachable)]
        [RequirePermission(PermissionType.None)]
        Id = 00,

        [PropertyType(PropertyTypeAttribute.GuidDefaultEnum.Empty)]        
        [Alias("ParentID")]
        [Cachable(PropertyCacheOptions.Cachable)]
        [RequirePermission(PermissionType.None)]
        ParentId,

        /// <summary>
        /// Indicate the supported properties.        
        /// return CachedProperties + the value set by PropertyHost.
        /// </summary>
        [PropertyType(typeof(object[]))]
        [RequirePermission(PermissionType.None)]
        SupportedProperties,

        /// <summary>
        /// Indicate the properties now cached in the current IPropertyCache.
        /// Property are cached using IPropertyCache.SetPropertyAsync.
        /// </summary>
        [PropertyType(typeof(object[]))]
        [RequirePermission(PermissionType.None)]
        CachedProperties,

        /// <summary>
        /// Indicate the properties now changed in the current IPropertyCache.
        /// Property are cached using IPropertyCache.SetPropertyAsync.
        /// </summary>
        [PropertyType(typeof(object[]))]
        [RequirePermission(PermissionType.None)]
        ChangedProperties,

        [PropertyType(typeof(IPropertyDefinitions[]))]
        [RequirePermission(PermissionType.None)]
        SupportedDefinitions,

        [PropertyType(typeof(string))]
        [RequirePermission(PermissionType.None)]
        OriginalType,

        /// <summary>
        /// Get when all properties are last cached (written to data store).
        /// </summary>
        [PropertyType(PropertyTypeAttribute.DateTimeDefaultEnum.Min)]
        [Alias("LastCached")]
        [ReturnMinOnly]
        LastCachedTimeUtc,    

        [PropertyType(PropertyTypeAttribute.DateTimeDefaultEnum.Min)]
        [Alias("LastListTime")]
        [ReturnMinOnly]
        LastListTimeUtc    
    }
       

    #endregion

    #region CofeProperties {10-49}
    /// <summary>
    /// {10-49} A list of properties for CofeSystemInfo
    /// </summary>
    [PropertyId(10, 49)]
    public enum CofeProperties : int
    {      
        /// <summary>
        /// Get the display label for the entries.
        /// </summary>
        [PropertyType(typeof(string))]
        [WebProperty(PropertyXmlType.Attribute)]
        [Alias("Label")]
        [Required]
        Label = 10,

        [PropertyType(typeof(IVolumeInfo))]        
        [RequirePermission(PermissionType.None, PermissionType.All)]
        [Cachable(PropertyCacheOptions.None, DatabaseCacheOptions.NotCachable)]
        VolumeInfo,

        /// <summary>
        /// Gets the name of the entries
        /// </summary>
        [PropertyType(typeof(string))]
        [FileName]
        Name,

        /// <summary>
        /// Get the path parsable by IUserProfile, with directory volume. (e.g. {ListerID}\Path)
        /// </summary>
        [PropertyType(typeof(string))]
        [PrimaryProperty]
        [WebProperty(PropertyXmlType.Element)]
        [Alias("Path")]
        [Cachable(PropertyCacheOptions.Cachable)] //Recreate if renamed.
        [RequirePermission(PermissionType.None)]
        [Required]
        FullParseName,
        
        /// <summary>
        /// Default type that the entry will be casted to.
        /// </summary>
        [PropertyType((object)typeof(ICofeSystemInfo), typeof(Type))]
        [Optional]
        DefaultInterfaceType,

        /// <summary>
        /// If cannot provide DefaultInterfaceType, provide it's full qualified name (e.g. Cofe.Core.ICofeSystemInfo)
        /// and CofePropertyProvider will provide DefaultInterfaceType.
        /// </summary>
        [PropertyType(typeof(string))]
        [Optional]
        [Alias("DefaultType")]
        [WebMetadata(false)]
        DefaultInterfaceTypeString,

        /// <summary>
        /// Base type of the entry (e.g. File/Folder), 
        /// btw, the Type property in CofeDirectoryPropertyies.CreateAsync use this format.
        /// </summary>
        [PropertyType(typeof(string))]
        [Required]
        [Alias("Type")]
        [WebMetadata(true)]
        [RequirePermission(PermissionType.None)]
        [Cachable(PropertyCacheOptions.Cachable, DatabaseCacheOptions.CachableORM)]
        Type,

        /// <summary>
        /// Get or Set the position of this entry relative to it's parent, 
        /// it's implement automatically by CofePropertyProvider if it's parent support GetPosition/SetPosition.
        /// </summary>
        [PropertyType(-1, typeof(int))]
        [Optional]
        [Alias("Position")]
        Position,

        /// <summary>
        /// Get COFEAttribute of the entries.
        /// </summary>
        [PropertyType(Cofe.Core.CofeAttributes.None, typeof(CofeAttributes), typeof(int))]
        [PrimaryProperty]
        [Required]
        CofeAttributes,

        /// <summary>
        /// Get whether the entries is exists.
        /// </summary>
        [PropertyType(typeof(bool))]
        [Optional]
        IsExists,

        /// <summary>
        /// Get the parent path parsable by IUserProfile.
        /// </summary>
        [PropertyType(null, typeof(string))]
        [WebMetadata(false)]
        [Alias("ParentPath")]
        [Optional] //Implement either ParentParseName or Parent.
        ParentParseName,

        /// <summary>
        /// PropertyProvider for parent.
        /// </summary>
        [PropertyType(typeof(IPropertyProvider))]        
        [Optional]
        ParentPropertyProvider,

        /// <summary>
        /// If either ParentParseName or ParentPropertyProvider defined, CofePropertyProvider provide this.
        /// </summary>
        [PropertyType(null, typeof(ICofeDirectoryInfo))]        
        [Alias("Parent")]
        [Optional]
        Parent,

        /// <summary>
        /// Get Last write time for an entries.
        /// </summary>
        [PropertyType(PropertyTypeAttribute.DateTimeDefaultEnum.Min)]
        [PrimaryProperty]      
        [Cachable(PropertyCacheOptions.Cachable | PropertyCacheOptions.Changeable)]
        LastWriteTimeUtc,


        /// <summary>
        /// Get Creation time for an entries.
        /// </summary>
        [PropertyType(PropertyTypeAttribute.DateTimeDefaultEnum.Min)]
        [Optional]
        CreationTimeUtc,


        /// <summary>
        /// Delete the current item, handled by MiscActionProvider or DBActionProvider, 
        /// which call DeleteCoreAsync action for actual deletion.
        /// </summary>
        [Action(ActionType.Async)]
        //[WebAction(WebAccessType.Action, RelationType.Delete, false)]
        [HandleOnes(HandleOnceActionMode.Compulsory)]
        [RequirePermission(PermissionType.Delete)]
        [Alias("Delete")]
        DeleteAsync,
  
        /// <summary>
        /// Move the current entry to the destination path.
        /// ToName - If rename, specify the name only.
        /// ToPath - If move to another directory, specify the full dest path      
        /// ToDirectory - destination directory.
        /// </summary>
        [Action(ActionType.Async, typeof(IPropertyProvider), "ToPath", "ToName", "ToDirectory")]
        [RequirePermission(PermissionType.Read)]
        [HandleOnes(HandleOnceActionMode.Compulsory)]
        MoveAsync,

        /// <summary>
        /// Tell all property providers to refresh the properties.
        /// PropertyCache calls ResetCache() as well.
        /// </summary>
        [Action(ActionType.Async)]
        [WebAction(WebAccessType.Action, RelationType.Refresh, false)]
        [AggregateResult]
        [Alias("Refresh")]
        RefreshAsync,

        /// <summary>
        /// For COFEWS3, Return a list of XmlLink structure, which is then serialize into xml.
        /// </summary>
        [ListAction(ActionType.Sync, typeof(XmlLink), "Scheme", "Host")]        
        [AggregateResult]        
        ListLinks
    }
    #endregion
  
    #region CofeDirectoryProperties {50-69}
    /// <summary>
    /// {50-69} A list of properties for DirectoryInfo.
    /// </summary>    
    [PropertyId(50, 69)]
    public enum CofeDirectoryProperties : int
    {
        /// <summary>
        /// Original list mode, return IEnumerable so enable propcessing asap.
        /// Implemented by PrimaryPropertyProvider.
        /// </summary>
        [ListAction(ActionType.Sync, typeof(IPropertyProvider))]
        [HandleOnes]
        [RelatedAction(ActionType = ActionType.Async, Property = CofeDirectoryProperties.ListCoreAsync)]
        ListCore = 50,

        /// <summary>
        /// New async list mode, return only when whole operation is completed.
        /// Implemented by PrimaryPropertyProvider.
        /// </summary>
        [ListAction(ActionType.Async, typeof(IPropertyProvider))]
        [HandleOnes]
        [RelatedAction(ActionType = ActionType.Sync, Property = CofeDirectoryProperties.ListCore)]
        ListCoreAsync,

        /// <summary>
        /// List that support entry and option filters.
        /// Implemented by CoreSecondaryPropertyProvider.
        /// </summary>
        [ListAction(ActionType.Sync, typeof(ICofeSystemInfo), "EntryFilters", "OptionFilters", "EnableCache")]
        [HandleOnes]
        [RequirePermission(PermissionType.List)]
        [WebListResource(MediaType.EntryList, RelationType.List, true)]
        [Alias("List")]
        [RelatedAction(ActionType = ActionType.Async, Property = CofeDirectoryProperties.ListAsync)]        
        List,

        /// <summary>
        /// List that support entry and option filters.
        /// Implemented by CoreSecondaryPropertyProvider.
        /// </summary>
        [ListAction(ActionType.Async, typeof(ICofeSystemInfo), "EntryFilters", "OptionFilters", "EnableCache")]       
        [HandleOnes]
        [RequirePermission(PermissionType.List)]
        [RelatedAction(ActionType = ActionType.Sync, Property = CofeDirectoryProperties.List)]
        ListAsync,

        /// <summary>
        /// Add the item to add list, calling Commit/CommitAsync will execute all stored actions.
        /// Type - "File", "Folder" or VirtualFolder type e.g. "zip"
        /// Name - File or folder name.
        /// </summary>
        [Action(ActionType.Async, typeof(IPropertyProvider), "Type", "Name")]
        [RequirePermission(PermissionType.Create)]
        [HandleOnes(HandleOnceActionMode.Compulsory)]
        [Cachable(PropertyCacheOptions.DefaultRequireConnected, DatabaseCacheOptions.NotCachable)]
        CreateAsync,

        /// <summary>
        /// Return position of the specified sub-entry.
        /// </summary>
        [Action(ActionType.Sync, typeof(int), "EntryPP", "Position")]
        GetPosition,

        /// <summary>
        /// Change position of the specified sub-entry, after it's added.
        /// </summary>
        [Action(ActionType.Sync, "EntryPP", "Position")]
        [RequirePermission(PermissionType.Write)]
        SetPosition,       

        /// <summary>
        /// Whether the directory contains subfolders, for reference only.
        /// </summary>
        [PropertyType(typeof(bool))]
        [WebMetadata(false)]        
        [Alias("HasSubFolders")]
        [Optional]
        HasSubFolders,

        /// <summary>
        /// Whether the directory contains files, for reference only.
        /// </summary>
        [PropertyType(typeof(bool))]
        [WebMetadata(false)]
        [Alias("HasFiles")]
        [Optional]
        HasFiles,
    }
    #endregion

    #region CofeItemProperties {70-79}
    /// <summary>
    /// {70-79} A list of properties for CofeItemInfo.
    /// </summary>
    [PropertyId(70, 79)]
    public enum CofeItemProperties : int
    {
        /// <summary>
        /// Get the size of a file.
        /// </summary>
        [PropertyType(typeof(Int64))]
        [PrimaryProperty]
        [WebMetadata(true)]
        [Alias("Size")]
        [Cachable(PropertyCacheOptions.Default, Core.DatabaseCacheOptions.CachableORM)]
        [Optional]
        Length = 70

    }
    #endregion

    #region CofeStreamProperties {80-89}
    /// <summary>
    /// {80-89} A list of properties for Stream related.
    /// </summary>
    [PropertyId(80, 89)]
    public enum CofeStreamProperties
    {
        [StreamAction(ActionType.Async, System.IO.FileAccess.Read, "Progress")]
        //[WebResource(MediaType.Stream, RelationType.Stream, false, WebCacheMethod.None)]
        //[Alias("Stream")]
        [RequirePermission(PermissionType.Read)]
        OpenReadAsync = 80,

        [StreamAction(ActionType.Async, System.IO.FileAccess.Write, "Progress")]
        [RequirePermission(PermissionType.Write)]
        OpenWriteAsync,

        [StreamAction(ActionType.Async, System.IO.FileAccess.Write | System.IO.FileAccess.Write, "Progress")]        
        [RequirePermission(PermissionType.Read | PermissionType.Write)]                
        OpenReadWriteAsync,

        /// <summary>
        /// Get the CRC checksum of a file.
        /// </summary>
        [PropertyType(typeof(string))]
        [Cachable(PropertyCacheOptions.Default, DatabaseCacheOptions.CachablePropertyPairs)]
        [WebMetadata(false)]
        [Alias("Crc")]
        [Optional]
        CRC,

        /// <summary>
        /// Get the MD5 checksum of a file.
        /// </summary>
        [PropertyType(typeof(string))]
        [Cachable(PropertyCacheOptions.Default, DatabaseCacheOptions.CachablePropertyPairs)]
        [WebMetadata(false)]
        [Alias("Md5")]
        [Optional]
        MD5,

        [PropertyType(typeof(StreamContainer))]
        [Alias("Stream")]
        [HandleOnes]
        [Cachable(PropertyCacheOptions.RequireConnected, Core.DatabaseCacheOptions.NotCachable)]
        [WebResource(MediaType.Stream, RelationType.Stream, true, WebCacheMethod.None)]
        [RequirePermission(PermissionType.Read | PermissionType.Write)]
        Stream

    }
    #endregion

    #region CofeIconProperties  {90-99}
    /// <summary>
    /// {90-99} Getting Icon and Thumbnail
    /// </summary>
    [PropertyId(90, 99)]
    public enum CofeIconProperties : int
    {
        //[PropertyType(typeof(IResourceList))]
        //[ResourceList(IconProperties.SmallIcon, IconProperties.LargeIcon, IconProperties.ExtraLargeIcon, IconProperties.JumboIcon)]
        //[Resource(MediaType.ResourceList, true)]
        //[Alias("Icon")]
        //Icon = 90,

        ///// <summary>
        ///// Return an resource list that contains all supported thumbnail.
        ///// e.g. Small.png, 
        ///// </summary>
        //[PropertyType(typeof(IResourceList))]
        //[ResourceList(IconProperties.SmallThumbnail, IconProperties.MediumThumbnail, IconProperties.LargeThumbnail)]
        //[Resource(MediaType.ResourceList, true)]
        //[Alias("Thumbnail")]
        //Thumbnail,

        /// <summary>
        /// Gets the Small Icon (16x16)
        /// </summary>
        [PropertyType(typeof(BitmapContainer))]
        [BitmapSize(16, 16)]
        [WebResource(MediaType.Png, false, WebCacheMethod.MaxAge)]
        [Alias("SmallIcon")]
        SmallIcon = 90,

        /// <summary>
        /// Gets the Large Icon (64x64)
        /// </summary>
        [PropertyType(typeof(BitmapContainer))]
        [BitmapSize(32, 32)]
        [WebResource(MediaType.Png, false, WebCacheMethod.MaxAge)]
        [Alias("LargeIcon")]
        LargeIcon,

        /// Gets the Extra Large Icon (128x128)
        /// </summary>
        [PropertyType(typeof(BitmapContainer))]
        [BitmapSize(128, 128)]
        [WebResource(MediaType.Png, false, WebCacheMethod.MaxAge)]
        [Alias("ExtraLargeIcon")]
        ExtraLargeIcon,

        /// <summary>
        /// Gets the Jumbo Icon (256x256)
        /// </summary>
        [PropertyType(typeof(BitmapContainer))]
        [BitmapSize(256, 256)]
        [WebResource(MediaType.Png, false, WebCacheMethod.MaxAge)]
        [Alias("JumboIcon")]
        JumboIcon,

        /// <summary>
        /// Get thumbnail of a image. (128x96).
        /// </summary>
        [PropertyType(typeof(BitmapContainer))]
        [BitmapSize(128)]
        [WebResource(MediaType.Png, false, WebCacheMethod.MaxAge)]
        [Alias("SmallThumbnail")]
        SmallThumbnail,

        /// <summary>
        /// Get thumbnail of a image. (256x192).
        /// </summary>
        [PropertyType(typeof(BitmapContainer))]
        [BitmapSize(256)]
        [WebResource(MediaType.Png, false, WebCacheMethod.MaxAge)]
        [Alias("MediumThumbnail")]
        MediumThumbnail,

        /// <summary>
        /// Get thumbnail of a image. (512x384).
        /// </summary>
        [PropertyType(typeof(BitmapContainer))]
        [BitmapSize(512)]
        [WebResource(MediaType.Png, false, WebCacheMethod.MaxAge)]
        [Alias("LargeThumbnail")]
        LargeThumbnail
    }
    #endregion

    #region CofeEntryLinkProperties {100-109}
    /// <summary>
    /// {100-109} A list of properties for CofeSystemInfo
    /// </summary>
    [PropertyId(100, 109)]
    public enum CofeEntryLinkProperties : int
    {
        /// <summary>
        /// Get the entry linked by the IEntryLink.
        /// </summary>
        [PropertyType(typeof(IPropertyHost))]                
        LinkedEntryPH = 100,

        /// <summary>
        /// Delete the current item as a link.     
        /// </summary>
        [Action(ActionType.Sync)]
        [WebAction(WebAccessType.Action, RelationType.Delete, false)]
        [HandleOnes(HandleOnceActionMode.Compulsory)]
        [RequirePermission(PermissionType.Delete)]
        [Alias("DeleteLink")]
        DeleteLink,

        ///New code :

        [Action(ActionType.Sync, typeof(IPropertyHost), "ParseName", "ParseType", "Label")]
        [HandleOnes(HandleOnceActionMode.Compulsory)]
        AddLink,

        [Action(ActionType.Sync, "Label")]
        [HandleOnes(HandleOnceActionMode.Compulsory)]
        DeleteChildLink,

        [ListAction(ActionType.Sync, typeof(IPropertyHost))]        
        GetLinks
    }
    #endregion

    #region CofeEntryListProperties {110-129}

    /// <summary>
    /// {110-129} Related to entry list.
    /// </summary>
    [PropertyId(110, 129)]
    public enum CofeEntryListProperties : int
    {
        [PropertyType(typeof(EntryListTypes))]
        [PrimaryProperty]
        EntryListType = 110,

        [PropertyType(false, typeof(bool))]
        [Cachable(PropertyCacheOptions.Default, DatabaseCacheOptions.CachablePropertyPairs)]
        IsAttached,

        /// <summary>
        /// If AutoEntryList (CofeProperties.Type = "Auto"), set or get the entry and option filters.
        /// </summary>
        [PropertyType(typeof(string))]
        [PrimaryProperty]
        [Optional]
        [Alias("FilterString")]
        [WebMetadata(true)]
        FilterString,        

        /// <summary>
        /// If AutoEntryList (CofeProperties.Type = "Auto"), start searching if it havent.        
        /// </summary>        
        [Action(ActionType.Async, "Progress")]
        //[RequirePermission(PermissionType.Execute)]
        SearchAsync

        //[PropertyType(typeof(IEnumerable<IPropertyHost>))]
        //SearchResult
    }
    #endregion

    #region CofeEntryTypeProperties {130-139}

    /// <summary>
    /// {130-139} Related to entry type
    /// </summary>
    [PropertyId(130, 139)]
    public enum CofeEntryTypeProperties : int
    {
        [PropertyType(typeof(string))]        
        EntryTypeKey = 130,

        [PropertyType(typeof(IEntryTypeInfo))]        
        EntryTypeInfo
    }

    #endregion

  
}

